package com.beidouapp.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.beidouapp.common.enums.RoleGroupType;
import com.beidouapp.common.util.SystemConfig;
import com.beidouapp.dao.OrganizationAndRoleDao;
import com.beidouapp.dao.OrganizationDao;
import com.beidouapp.dao.RoleDao;
import com.beidouapp.domain.pojo.Employee;
import com.beidouapp.domain.pojo.Organization;
import com.beidouapp.domain.pojo.OrganizationAndRole;
import com.beidouapp.domain.pojo.Resource;
import com.beidouapp.domain.pojo.Role;
import com.beidouapp.domain.pojo.RoleAndResource;
import com.beidouapp.domain.pojo.RoleAndResourceVO;
import com.beidouapp.exception.BusinessException;
import com.beidouapp.security.model.SessionUser;
import com.beidouapp.service.EmployeeService;
import com.beidouapp.service.ResourceService;
import com.beidouapp.service.RoleService;
import com.beidouapp.translator.TranslatorManager;
import com.beidouapp.utils.UIUtils;

@Service
public class RoleServiceImpl implements RoleService {

	public static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);

	@Autowired
	private RoleDao roleDao;
	
	@Autowired
	private OrganizationDao organizationDao;

	@Autowired
	private OrganizationAndRoleDao organizationAndRoleDao;

	@Autowired
	private EmployeeService employeeService;

	@Autowired
	private ResourceService resourceService;

	@Autowired
	private TranslatorManager translatorManager;
	

	@Override
	public List<Role> findRolesByEmpId(Long userId) {
		List<Role> roles = roleDao.findRolesByEmpId(userId);
		return translatorManager.translate(roles);
	}

	@Override
	public List<Role> findRolesByOrgId(Long orgId) {
		List<Role> roles = roleDao.findRolesByOrgId(orgId);
		return translatorManager.translate(roles);
	}

	@Override
	public Role getRoleById(Long roleId) {
		if (roleId == null) {
			throw new BusinessException("角色ID为空");
		}
		Role role = roleDao.getEntryByID(roleId.longValue());
		if (role == null) {
			throw new BusinessException("角色不存在");
		}
		return translatorManager.translate(role);
	}
	
	@Override
	public int saveOrUpdateRole(Role role) {
		if (role == null || StringUtils.isEmpty(role.getCode())) {
			throw new BusinessException("角色或角色编码不能为空");
		}
		int rs = 0;
		if (role.getId() == null) {
			Role role_db = roleDao.findRolesByRoleCode(role.getCode());
			if (role_db != null) {
				throw new BusinessException("角色代码在系统中已存在");
			}
			SessionUser user = UIUtils.getSessionUser();
			if (user.getOrgId() != null) {
				role.setRoleGroupId(RoleGroupType.BUSINESS_ROLE.getCode());
			}
			role.setCreateDate(new Date());
			rs = roleDao.insert(role);

			if (user.getOrgId() != null) {
				role_db = roleDao.findRolesByRoleCode(role.getCode());
				if (role_db == null)
					throw new BusinessException("角色新增失败");
				OrganizationAndRole orgRole = new OrganizationAndRole();
				orgRole.setOrgId(user.getOrgId());
				orgRole.setRoleId(role_db.getId());
				organizationAndRoleDao.addEntry(orgRole);
			}
		} else {
			SessionUser user = UIUtils.getSessionUser();
			if (user.getOrgId() != null) {
				role.setRoleGroupId(RoleGroupType.BUSINESS_ROLE.getCode());
			}
			rs = roleDao.update(role);
		}
		return rs;
	}

	@Override
	public List<Role> findRoleList(Role role) {
		List<Role> list = roleDao.findEntryList(role);
		return translatorManager.translate(list);
	}

	@Override
	public List<Role> findRolesByMap(Map<String, Object> params) {
		List<Role> list = roleDao.findRolesByMap(params);
		return translatorManager.translate(list);
	}

	// --------------------

	@Override
	public List<Role> findPageRoles(Map<String, Object> params, Integer offset, Integer limit) {
		List<Role> roles = roleDao.findPageRoles(params, offset, limit);
		return translatorManager.translate(roles);
	}

	@Override
	public long countPageRoles(Map<String, Object> params) {
		return roleDao.countPageRoles(params);
	}

	@Override
	public void removeRoles(Long... roleIds) {
		Long tempId = null;
		try {
			for (Long id : roleIds) {
				tempId = id;
				List<Employee> employeeList = employeeService.findEmployeeListByRoleId(id);
				List<Resource> resourceList = resourceService.findRoleResourcesByRoleId(id);
				if (!(CollectionUtils.isEmpty(employeeList) && CollectionUtils.isEmpty(resourceList))) {
					logger.error("角色id={} 已关联用户和资源，请先取消后再删除!", id);
					throw new BusinessException("10", "当前角色已关联用户和资源，请先取消后再删除.");
				}
				this.roleDao.removeEntryByID(id);
			}
		} catch (Exception e) {
			logger.error("角色id={} 删除异常! because {}.", tempId, e.getLocalizedMessage(), e);
			throw new BusinessException("11", "角色删除异常。", e);
		}
	}
	
	
	@Override
	public void saveSyncRoleList(List<Role> syncList) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fkId", "0");
		List<Role> localList = roleDao.findRolesByMap(params);// 数据列表
		Organization org = this.getOrganization();
		if(org == null) return;
		for (Role vo : syncList) {
			//未启用的不存进来,存在的删除掉
			/*if(!vo.getStatus().equals("0")){
				deleteContactRole(vo,org);
			}*/
			if (!contains(localList, vo)) {// 不存在则存DB
				Role dbRole = roleDao.findRoleByFkId(vo.getFkId());
				vo.setRoleGroupId(Long.parseLong(SystemConfig.getConfig("datasystem.group_role_id.val")));// 标记为“双流机场”组
				if (dbRole == null) {
					saveFKRole(vo,org);
				} else {
					vo.setId(dbRole.getId());
					roleDao.update(vo);
				}
			}
		}
		for (Role vo : localList) {// 删除不存在的对象
			if (!contains(syncList, vo)) {
				deleteFKRole(vo,org);
			}
		}
	}

	public void saveSyncRoleList(Role role) {
	    Role dbRole = roleDao.findRoleByFkId(role.getFkId());// 数据列表
	    role.setRoleGroupId(Long.parseLong(SystemConfig.getConfig("datasystem.group_role_id.val")));
		Organization organization = getOrganization();
		if(organization==null) return;
		if(dbRole==null){
			saveFKRole(role,organization);
		}else{
			role.setId(dbRole.getId());
			roleDao.update(role);
		}
	}
	
	public void saveFKRole(Role role,Organization org){
		roleDao.addEntry(role);
		Role roletmp = roleDao.findRoleByFkId(role.getFkId());
		OrganizationAndRole  organizationAndRole = new OrganizationAndRole();
		organizationAndRole.setOrgId(org.getId());
		organizationAndRole.setRoleId(roletmp.getId());
		organizationAndRoleDao.addEntry(organizationAndRole);
	}
	
	public void  deleteFKRole(Role vo,Organization org){
		OrganizationAndRole  organizationAndRole = new OrganizationAndRole();
		organizationAndRole.setOrgId(org.getId());
		organizationAndRole.setRoleId(vo.getId());
		organizationAndRoleDao.removeEntry(organizationAndRole);
		resourceService.removeRoleAndResourceByRoleId(vo.getId());
		roleDao.removeEntryByFKID(vo.getFkId());
	}

	private boolean contains(List<Role> list, Role elem) {
		for (Role vo : list)
			if (elem.getFkId().equals(vo.getFkId()))
				return true;
		return false;
	}

	@Override
	public List<Role> findRolesByDepartmentId(String departmentId) {
		return roleDao.findRolesByDepartmentId(departmentId);
	}

	@Override
	public Role getRoleByCode(String roleCode) { 
		return roleDao.findRolesByRoleCode(roleCode);
	}

	@Override
	public Role getRolesByFKId(String roleFKId) {
		return roleDao.findRoleByFkId(roleFKId);
	}

	@Override
	public void deleteContactRoleByFKId(String roleFKId) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fkId", roleFKId);
		List<Role> localList = roleDao.findRolesByMap(params);// 数据列表
		Organization organization = getOrganization();
		if(organization==null) return;
		for (Role vo : localList) {
			deleteFKRole(vo,organization);
		}
	}
	
	public Organization getOrganization(){
		String orgCode = SystemConfig.getConfig("systeminfo.org.code");
		Organization organization = new Organization();
		organization.setCode(orgCode);
		List<Organization> organizations =  organizationDao.findEntryList(organization);
		if(organizations==null||organizations.isEmpty()){
			return null;
		}
		Organization org = organizations.get(0);
		return org;
	}
	
	public void saveSyncAllRoleAndResourceList(List<RoleAndResourceVO> roleAndResourceList) {
		
	}

	@Override
	public void saveSyncRoleAndResourceList(Map<String,List<RoleAndResourceVO>> roleAndResourceMap) {
		Organization org =  getOrganization();
		if(org==null) return;
		//查询组织下的所有角色
		List<Role> roles = roleDao.findRolesByOrgId(org.getId());
		//查询系统下的所有资源
		List<Resource> resources = resourceService.findAllResource();
		//提取角色与资源的对应关系
		Map<String,Long> resourtceMap = new HashMap<String,Long>();
		Map<String,Long> roleMap = new HashMap<String,Long>();
		for(Resource r: resources){
			if(StringUtils.isBlank(r.getCode())) continue;
			resourtceMap.put(r.getCode(), r.getId());
		}
		for(Role r: roles){
			if(StringUtils.isBlank(r.getFkId())) continue;
			roleMap.put(r.getFkId(), r.getId());
		}
		
		Iterator<Map.Entry<String,List<RoleAndResourceVO>>> it = roleAndResourceMap.entrySet().iterator();
		while(it.hasNext()){
			List<RoleAndResource> roleRs = new ArrayList<RoleAndResource>();
			Map.Entry<String,List<RoleAndResourceVO>> entry = it.next();
			String key = entry.getKey();
			List<RoleAndResourceVO> value = entry.getValue();
			Long roleId =	roleMap.get(key);
			if(roleId==null) continue;
			for(RoleAndResourceVO roleAndResource : value){
				  Long resourceId = resourtceMap.get(roleAndResource.getResourceCode());
				  if(resourceId==null) continue;
				  RoleAndResource rolersObj = new RoleAndResource();
				  rolersObj.setResourceId(resourceId);
				  rolersObj.setRoleId(roleId);
				  roleRs.add(rolersObj);
			}
		
			resourceService.removeRoleAndResourceByRoleId(roleId);
			if(!roleRs.isEmpty()){
			 resourceService.addRoleAndResourceBatch(roleRs);
			}
		}
	}

}
